package com.wqj.ride.happyriding.bluetooth.bt.manager

import android.bluetooth.BluetoothSocket
import android.util.Log
import com.wqj.ride.happyriding.base.Communicator
import com.wqj.ride.happyriding.bluetooth.bt.bean.BluetoothDeviceDean
import com.wqj.ride.happyriding.bluetooth.bt.callback.BtConnectResult
import com.wqj.ride.happyriding.bluetooth.bt.BtDevicesActivity

import java.io.IOException
import java.io.OutputStream
import java.util.*
import java.util.concurrent.locks.ReentrantLock


/**
 * Created by kyee on 17-12-8.
 */
public class BtManager() : Thread(), Communicator {
    private var mmSocket: BluetoothSocket? = null
    private var mmDevice: BluetoothDeviceDean? = null
    private var mConnectResult: BtConnectResult? = null
    private var mOutputStream: OutputStream? = null
    private val lock = ReentrantLock()

//    private var mHandler: Handler
//    private var isConnected = false;

    init {
        // Use a temporary object that is later assigned to mmSocket,
        // because mmSocket is final
    }

    override @Synchronized fun run() {
        // Cancel discovery because it will slow down the connection
        Log.d(TAG, "Start connect to bt-gps: " + mmSocket)
        try {
            // Connect the device through the socket. This will block
            // until it succeeds or throws an exception
            mmSocket!!.connect()
            Log.d(TAG, "connect bt success")
            mOutputStream = mmSocket!!.outputStream
            mmDevice!!.isContected = true
            mConnectResult?.onSuccess()
        } catch (connectException: IOException) {
            // Unable to connect; close the socket and get out
            Log.d(TAG, "connect bt failed: " + connectException.message)
            mConnectResult?.onFailure()
            try {
                mmSocket!!.close()
            } catch (closeException: IOException) {
            }

        }
        // Do work to manage the connection (in a separate thread)
        // manageConnectedSocket(mmSocket)
    }

    @Synchronized fun connect(device: BluetoothDeviceDean, callback: BtConnectResult) {
        var tmp: BluetoothSocket? = null
        val uuid = UUID.fromString(BtDevicesActivity.BT_UUID)
        Log.d(TAG, "Start client connect thread")

        if (null != mmDevice
                && device.bluetoothDevice.address.equals(mmDevice!!.bluetoothDevice.address)) {
            return
        }
        // 断开先前的连接
        disconnect()
        mmDevice = device
        mConnectResult = callback
        // Get a BluetoothSocket to connect with the given BluetoothDevice
        try {
            // MY_UUID is the app's UUID string, also used by the server code
            tmp = mmDevice!!.getBluetoothDevice().createRfcommSocketToServiceRecord(uuid)
        } catch (e: IOException) {
        }
        mmSocket = tmp
        this.start()
    }

    override fun send(bytes: ByteArray) {
        mOutputStream!!.write(bytes)
        Log.d(TAG, "writing data to bt device")
    }

    override fun receive(bytes: ByteArray) {
        Log.d(TAG, "received data size: " + bytes.size)
    }

    /** Will cancel an in-progress connection, and close the socket  */
    override fun disconnect() {
        mmDevice?.isContected = false
        try {
            mmSocket?.close()
            Log.d(TAG, "bluetooth device disconnected")
        } catch (e: IOException) {
        }
        mmDevice = null
        mmSocket = null
    }

    override fun isConnected() :Boolean{
        if (null == mmDevice || null == mmSocket) {
            return false
        }
        return mmSocket!!.isConnected()
    }

    fun getConnectedDevice() : BluetoothDeviceDean {
        return mmDevice!!
    }

    companion object{
        private val TAG: String = "BtManager"
        private val mBtManager: BtManager = BtManager()

        public fun getInstance(): BtManager {
            return mBtManager
        }
    }
}